/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package project2;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
    
/**
 *
 * @author rr
 */
public class Run {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception, FileNotFoundException {
       
        
        int problemNo = 3;
        if(args.length == 1){
            problemNo = Integer.parseInt(args[0]);
        }
        
        int kOpt = 1;
        float startStochasticHillClimbingT = 1f;
        float simulatedAnnealingR = 0.00003f;
        int stopLimit = 10; //  -1: only use heuristic
        boolean decreaseEveryTime = true;

        if(args.length == 6){
            //a
             problemNo = Integer.parseInt(args[0]);
             kOpt = Integer.parseInt(args[1]);
             startStochasticHillClimbingT = Float.parseFloat(args[2]);
             simulatedAnnealingR = Float.parseFloat(args[3]);
             stopLimit = Integer.parseInt(args[4]);
             decreaseEveryTime = Boolean.parseBoolean(args[5]);
        }
        
        long startTime = System.currentTimeMillis();
   
        File problemFile = new File("res/problemSets/Example"+problemNo+".txt");
       
        //new setup
        SetUp.getInstance().init(problemFile);
        
        SetUp.getInstance().setkOpt(kOpt);
        SetUp.getInstance().setStartStochasticHillClimbingT(startStochasticHillClimbingT);
        SetUp.getInstance().setStochasticHillClimbingT(startStochasticHillClimbingT);
        SetUp.getInstance().setSimulatedAnnealingR(simulatedAnnealingR);
        SetUp.getInstance().setStopLimit(stopLimit);
        SetUp.getInstance().setDecreaseTEveryTime(decreaseEveryTime);
        
        //for direct solving...
        project1.SetUp.getInstance().init(problemFile);
        
        project2.Solver.getInstance().solve();
        //printWorkSchedule(Solver.getInstance().getBestSolution());
        // ... do something ...
        long estimatedTime = System.currentTimeMillis() - startTime;
       
        printWorkScheduleToFile(Solver.getInstance().getBestSolution().getAssignments(), "solutions/SolutionHeuristic"+problemNo+".txt", estimatedTime);
        
        
        
    }
    
    
    
    public static void printWorkScheduleToFile(int[] solution, String filepath, long estimatedTime) throws FileNotFoundException, UnsupportedEncodingException{
        PrintWriter writer = new PrintWriter(filepath, "UTF-8");
        for(int i = 0; i < SetUp.getInstance().getNumberOfEmployees(); ++i){
            
            writer.print("Employee No"+i);
            
            for(int j = 0; j<SetUp.getInstance().getLengthOfSchedule(); ++j){
                String s;
                if(solution[(i*SetUp.getInstance().getLengthOfSchedule() + j)]!=-1)
                    s=SetUp.getInstance().getNames()[solution[(i*SetUp.getInstance().getLengthOfSchedule() + j)]];
                else
                    s="~";
                writer.print(" "+s+" ");
            }
            
            writer.println();
                
        }
        writer.println("Solution Finding took "+estimatedTime+" miliseconds");
        
        writer.println("parameter for k-opt k="+SetUp.getInstance().getkOpt());
        writer.println("parameter for stochastic hill climbing t="+SetUp.getInstance().getStartStochasticHillClimbingT());
        writer.println("parameter for simulated annealing r="+SetUp.getInstance().getSimulatedAnnealingR());
        writer.println("stop limit for heuristic - try exact solving: stopLimit="+SetUp.getInstance().getStopLimit());
        
        
        writer.close();
    }
    
    public static void printWorkSchedule(Solution solution){
        
        System.out.println("SOLUTION ERROR= "+solution.getError());
        System.out.println("BLOCK ERROR= "+solution.getBlockError());
        System.out.println("BLOCK ARRAY= "+Arrays.toString(solution.getBlockIsValid()));
        System.out.println();
        for (int i = 0 ; i < solution.getBlockIsValid().length ; i++) {
            if (!solution.getBlockIsValid()[i]) {
                System.out.print(" | "+i);
                // This is where you print i or do whatever else you think is appropriate
            }
        }
        System.out.println();
        System.out.println("SEQ ERROR= "+solution.getSeqError());
        if(solution == null){
            System.out.println("no solution");
            return;
        }
        
        for(int i = 0; i < SetUp.getInstance().getNumberOfEmployees(); ++i){
            
            System.out.print("Employee No"+i);
            
            for(int j = 0; j<SetUp.getInstance().getLengthOfSchedule(); ++j){
                String s;
                if(solution.getAssignments()[(i*SetUp.getInstance().getLengthOfSchedule() + j)]!=-1)
                    s=SetUp.getInstance().getNames()[solution.getAssignments()[(i*SetUp.getInstance().getLengthOfSchedule() + j)]];
                else
                    s="~";
                System.out.print(" "+s+" ");
            }
            
            
            
            System.out.println();
                
        }
        
        System.out.println("SOLUTION ERROR= "+solution.getError());
        
    }
    public static void printWorkSchedule(int[] solution){
        
        if(solution == null){
            System.out.println("no solution");
            return;
        }
        
        for(int i = 0; i < SetUp.getInstance().getNumberOfEmployees(); ++i){
            
            System.out.print("Employee No"+i);
            
            for(int j = 0; j<SetUp.getInstance().getLengthOfSchedule(); ++j){
                String s;
                if(solution[(i*SetUp.getInstance().getLengthOfSchedule() + j)]!=-1)
                    s=SetUp.getInstance().getNames()[solution[(i*SetUp.getInstance().getLengthOfSchedule() + j)]];
                else
                    s="~";
                System.out.print(" "+s+" ");
            }
            
            
            
            System.out.println();
                
        }
        
    }
}
